package com.im.sdk.server.network;

import com.im.sdk.server.ServerCoreHandler;
import io.netty.util.AttributeKey;
import io.netty.channel.Channel;

public abstract class Gateway
{
    public final static String SOCKET_TYPE_IN_CHANNEL_ATTRIBUTE = "__socket_type__";
    public static final AttributeKey<Integer> SOCKET_TYPE_IN_CHANNEL_ATTRIBUTE_ATTR = AttributeKey.newInstance(SOCKET_TYPE_IN_CHANNEL_ATTRIBUTE);

    public static final int SOCKET_TYPE_UDP       = 0x0001;
    public static final int SOCKET_TYPE_TCP       = 0x0002;
    public static final int SOCKET_TYPE_WEBSOCKET = 0x0004;

    public abstract void init(ServerCoreHandler serverCoreHandler);
    public abstract void bind() throws Exception;
    public abstract void shutdown();

    public static void setSocketType(Channel c, int socketType)
    {
        c.attr(SOCKET_TYPE_IN_CHANNEL_ATTRIBUTE_ATTR).set(socketType);
    }

    public static void removeSocketType(Channel c)
    {
        c.attr(SOCKET_TYPE_IN_CHANNEL_ATTRIBUTE_ATTR).set(null);
    }

    public static int getSocketType(Channel c)
    {
        Integer socketType = c.attr(SOCKET_TYPE_IN_CHANNEL_ATTRIBUTE_ATTR).get();
        if(socketType != null)
            return socketType.intValue();
        return -1;
    }

    public static boolean isSupportUDP(int support)
    {
        // 位运算
        return (support & SOCKET_TYPE_UDP) == SOCKET_TYPE_UDP;
    }

    public static boolean isSupportTCP(int support)
    {
        // 位运算
        return (support & SOCKET_TYPE_TCP) == SOCKET_TYPE_TCP;
    }

    public static boolean isSupportWebSocket(int support)
    {
        // 位运算
        return (support & SOCKET_TYPE_WEBSOCKET) == SOCKET_TYPE_WEBSOCKET;
    }

    public static boolean isTCPChannel(Channel c)
    {
//		return (c != null && c instanceof NioSocketChannel);
        return (c != null && getSocketType(c) == SOCKET_TYPE_TCP);
    }

    public static boolean isUDPChannel(Channel c)
    {
//		return (c != null && c instanceof MBUDPChannel);
        return (c != null && getSocketType(c) == SOCKET_TYPE_UDP);
    }

    public static boolean isWebSocketChannel(Channel c)
    {
        return (c != null && getSocketType(c) == SOCKET_TYPE_WEBSOCKET);
    }

    public static String $(Channel c)
    {
        return getGatewayFlag(c);
    }

    public static String getGatewayFlag(Channel c)
    {
//		logger.info(">>>>>> c.class="+c.getClass().getName());
        if(Gateway.isUDPChannel(c))
            return "udp";
        else if(Gateway.isTCPChannel(c))
            return "tcp";
        else if(Gateway.isWebSocketChannel(c))
            return "websocket";
        else
            return "unknow";
    }
}
